﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;


namespace DDD {
    /// <summary>
    /// <see cref="Appearance"/>クラスに拡張メソッドを追加するクラス
    /// </summary>
    public static class AppearanceExtensions {

        /// <summary>
        /// コンパイル
        /// </summary>
        /// <param name="app"><see cref="Appearance"/>オブジェクト</param>
        public static void Compile (this Appearance app) {
            var sp = app.ShaderProgram;
            var cmp = app.CompositeMode;
            var texs = app.Samplers;
            var pmode = app.PolygonMode;

            if (sp != null) {
                sp.Compile ();
            }
            if (cmp != null) {
                cmp.Compile ();
            }
            if (pmode != null) {
                pmode.Compile ();
            }

            foreach (var tex in texs) {
                tex.Compile ();
            }
            
        }

        /// <summary>
        /// レンダリング
        /// </summary>
        /// <param name="app"><see cref="Appearance"/>オブジェクト</param>
        /// <param name="node">カレントのノード</param>
        public static void Render (this Appearance app, Node node) {
            var cache = Graphics3DExtensions.GetGLCache ();
            var sp = app.ShaderProgram;
            var cmp = app.CompositeMode;
            var pmode = app.PolygonMode;
            var unifs = app.UniformArrays;

            if (sp != null) {
                sp.Render ();
            }

            // デフォルト
            GL.Disable (EnableCap.Blend);
            GL.Enable (EnableCap.DepthTest);
            GL.DepthFunc (DepthFunction.Lequal);
            GL.Enable (EnableCap.CullFace);
            GL.CullFace (CullFaceMode.Back);
            GL.FrontFace (FrontFaceDirection.Ccw);
            GL.DepthMask (true);
            GL.ColorMask (true, true, true, true);

            foreach (var unif in unifs) {
                unif.Render (sp, node, app);
            }

            if (cmp != null) {
                cmp.Render ();
            }
            if (pmode != null) {
                pmode.Render ();
            }

            foreach(var sam in app.Samplers) {
                var i = app.GetSamplerIndex (sam);
                sam.Render (i);
            }

        }

    }
}
